/*
 *
 * This file is part of the open-source SeetaFace engine, which includes three modules:
 * SeetaFace Detection, SeetaFace Alignment, and SeetaFace Identification.
 *
 * This file is part of the SeetaFace Detection module, containing codes implementing the
 * face detection method described in the following paper:
 *
 *
 *   Funnel-structured cascade for multi-view face detection with alignment awareness,
 *   Shuzhe Wu, Meina Kan, Zhenliang He, Shiguang Shan, Xilin Chen.
 *   In Neurocomputing (under review)
 *
 *
 * Copyright (C) 2016, Visual Information Processing and Learning (VIPL) group,
 * Institute of Computing Technology, Chinese Academy of Sciences, Beijing, China.
 *
 * The codes are mainly developed by Shuzhe Wu (a Ph.D supervised by Prof. Shiguang Shan)
 *
 * As an open-source face recognition engine: you can redistribute SeetaFace source codes
 * and/or modify it under the terms of the BSD 2-Clause License.
 *
 * You should have received a copy of the BSD 2-Clause License along with the software.
 * If not, see < https://opensource.org/licenses/BSD-2-Clause>.
 *
 * Contact Info: you can send an email to SeetaFace@vipl.ict.ac.cn for any problems.
 *
 * Note: the above information must be kept whenever or wherever the codes are used.
 *
 */

#ifndef SEETA_FD_FEAT_SURF_FEATURE_MAP_H_
#define SEETA_FD_FEAT_SURF_FEATURE_MAP_H_


#include "common.h"
#include "feature_map.h"
#include "math_func.h"



typedef struct SURFPatchFormat {
	/**< aspect ratio, s.t. GCD(width, height) = 1 */
	int32_t width;
	int32_t height;

	/**< cell partition */
	int32_t num_cell_per_row;
	int32_t num_cell_per_col;
} SURFPatchFormat;
typedef struct SURFFeature {
  Rect patch;
  int32_t num_cell_per_row;
  int32_t num_cell_per_col;
} SURFFeature;
typedef struct classSURFFeaturePool SURFFeaturePool;
struct classSURFFeaturePool{
  int32_t sample_width_;
  int32_t sample_height_;
  int32_t patch_move_step_x_;
  int32_t patch_move_step_y_;
  int32_t patch_size_inc_step_; /**< incremental step of patch width and */
                                /**< height when build feature pool      */
  int32_t patch_min_width_;
  int32_t patch_min_height_;

  SURFFeature pool_[56];
  SURFPatchFormat format_[5];
};
void ReleaseSURFFeaturePool(struct classSURFFeaturePool *p);
void SURFFeaturePoolCreate(struct classSURFFeaturePool *p);
void SURFFeaturePoolAddPatchFormat(struct classSURFFeaturePool *p, int index,int32_t width, int32_t height, int32_t num_cell_per_row,
	int32_t num_cell_per_col);
void SURFFeaturePoolAddAllFeaturesToPool(struct classSURFFeaturePool *p, int32_t width, int32_t height,
	int32_t num_cell_per_row, int32_t num_cell_per_col,int* poolindex);
//void InitSURFFeaturePool(struct classSURFFeaturePool *p, int sample_width = 40, int sample_height = 40,
//	int patch_move_step_x = 16, int patch_move_step_y = 16, int patch_size_inc_step = 1, int patch_min_width = 16, int patch_min_height = 16);
void InitSURFFeaturePool(struct classSURFFeaturePool *p, int sample_width , int sample_height ,
		int patch_move_step_x , int patch_move_step_y , int patch_size_inc_step , int patch_min_width , int patch_min_height );

bool SURFFeaturePoolempty(struct classSURFFeaturePool *p);
int SURFFeaturePoolsize(struct classSURFFeaturePool *p);

SURFFeature SURFFeaturePoolbegin(struct classSURFFeaturePool *p) ;

SURFFeature SURFFeaturePoolend(struct classSURFFeaturePool *p);

const SURFFeature SURFFeaturePoolidx(struct classSURFFeaturePool *p, size_t idx);

//static const int32_t kNumIntChannel = 8;
#define kNumIntChannel 8
typedef struct classSURFFeatureMap SURFFeatureMap;
struct classSURFFeatureMap{
	 
  bool buf_valid_reset_;

  int32_t* grad_x_;
  int32_t* grad_y_;
  int32_t* int_img_;
  int32_t* img_buf_;
  int32_t** feat_vec_buf_;
  float** feat_vec_normed_buf_;
  int32_t* buf_valid_;
  FeatureMap featuremap;
  SURFFeaturePool feat_pool_;
};
//void InitSURFFeatureMap(struct classSURFFeatureMap *p, bool buf_valid_reset = false);
void InitSURFFeatureMap(struct classSURFFeatureMap *p, bool buf_valid_reset );
void ReleaseSURFFeatureMap(struct classSURFFeatureMap *p);
void SURFFeatureMapCompute(struct classSURFFeatureMap *p, const uint8_t* input, int32_t width, int32_t height,FDHandle* handle);

void SURFFeatureMapGetFeatureVector(struct classSURFFeatureMap *p, int32_t featID, float* featVec);
void SURFFeatureMapInitFeaturePool(struct classSURFFeatureMap *p);
void SURFFeatureMapReshape(struct classSURFFeatureMap *p, int32_t width, int32_t height,FDHandle* handle);

void SURFFeatureMapComputeGradientImages(struct classSURFFeatureMap *p, const uint8_t* input);
void SURFFeatureMapComputeGradX(struct classSURFFeatureMap *p, const int32_t* input);
void SURFFeatureMapComputeGradY(struct classSURFFeatureMap *p, const int32_t* input);
void SURFFeatureMapComputeIntegralImages(struct classSURFFeatureMap *p);
void SURFFeatureMapIntegral(struct classSURFFeatureMap *p);
void SURFFeatureMapMaskIntegralChannel(struct classSURFFeatureMap *p);
void SURFFeatureMapComputeFeatureVector(struct classSURFFeatureMap *p, const SURFFeature  feat, int32_t* feat_vec);
void SURFFeatureMapNormalizeFeatureVectorL2(struct classSURFFeatureMap *p, const int32_t* feat_vec, float* feat_vec_normed, int32_t len);
void SURFFeatureMapVectorCumAdd(struct classSURFFeatureMap *p, int32_t* x, int32_t len, int32_t num_channel);

void SURFFeatureMapSetROI(struct classSURFFeatureMap *p, const Rect  roi);

int32_t SURFFeatureMapGetFeatureVectorDim(struct classSURFFeatureMap *p, int32_t feat_id);
void SURFFeatureMapFillIntegralChannel(struct classSURFFeatureMap *p, const int32_t* src, int32_t ch) ;
//}  // namespace fd
//}  // namespace seeta

#endif  // SEETA_FD_FEAT_SURF_FEATURE_MAP_H_
